package com.feinno.urcs.group.dao;

import com.feinno.database.DataRow;
import com.feinno.database.DataTable;
import com.feinno.database.Database;
import com.feinno.superpojo.generator.Field.StringFieldInterpreter;
import com.feinno.urcs.group.GroupConfiguration;
import com.feinno.urcs.group.GroupError;
import com.feinno.urcs.group.GroupException;
import com.feinno.urcs.group.api.FXUserIndexService;
import com.feinno.urcs.group.api.GroupCacheManager;
import com.feinno.urcs.group.api.GroupDao;
import com.feinno.urcs.group.entity.*;
import com.feinno.urcs.group.fxdb.FXPoolService;
import com.feinno.urcs.group.fxdb.PooledDatabaseLoader;
import com.feinno.urcs.group.interop.entity.FXCatalogIndex;
import com.feinno.urcs.group.util.DateUtils;
import com.feinno.urcs.types.MobileNo;
import com.feinno.util.StringUtils;
import org.helium.framework.annotations.FieldSetter;
import org.helium.framework.annotations.ServiceImplementation;
import org.helium.framework.annotations.ServiceSetter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.sql.SQLException;
import java.time.temporal.ChronoUnit;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * Created by honghao on 5/4/15.
 */

@ServiceImplementation
public class GroupDaoImpl implements GroupDao {
	private static final Logger LOGGER = LoggerFactory.getLogger(GroupDaoImpl.class);

	@FieldSetter("${GGRPDB}")
	private Database ggrpDb;

	@FieldSetter(value = "${GRPDB_POOLS_XML}", loader = PooledDatabaseLoader.class)
	private Map<Integer, Database> dbs;

	@ServiceSetter
	private FXPoolService poolService;

	@ServiceSetter
	private GroupCacheManager groupCache;
	@ServiceSetter
	private FXUserIndexService fxUserIndexService;

	/**
	 * 获取指定PhysicalPool的GRPDB
	 *
	 * @param index 群索引
	 * @return 返回Database连接
	 * @throws SQLException
	 */
	private Database getDatabase(GroupIndex index) throws Exception {
		int logicPool = index.getLogicalPool();
		if (logicPool == 0) {
			String sql = "SELECT LogicPool FROM GGRP_SearchGroup WHERE GroupId = ?";
			DataTable dt = ggrpDb.executeTable(sql, index.getGroupId());
			if (dt != null && dt.getRows().size() > 0) {
				logicPool = dt.getRow(0).getInt("LogicPool");
			} else {
				LOGGER.error(String.format("groupIndex LogicalPool is null index=%s ", index.toJsonObject().toString()));
			}
		}
		int poolid = poolService.getPhyicalPool(logicPool);
		return dbs.get(poolid);
	}

	/**
	 * select * from GRP_GroupInfo where GroupIndex = @GroupIndex
	 *
	 * @param index
	 * @return
	 */
	public GroupInfo getGroupInfo(GroupIndex index) throws Exception {

		// get groupInfo from redis first
		GroupInfo groupInfo = groupCache.getGroupInfo(index.getGroupId());
		if (null == groupInfo) {
			String infoSql = "select * from GRP_Group where groupId = ? ";
			String memberSql = "select * from GRP_GroupMember where GroupId = ? and MobileNo is not null";
			if (null == index) throw new GroupException(GroupError.GROUP_NOT_FOUND);
			// TODO getDb()
			DataTable infoDt = getDatabase(index).executeTable(infoSql, index.getGroupId());
			DataTable memberDt = getDatabase(index).executeTable(memberSql, index.getGroupId());
			List<GroupMember> groupMemberList = new ArrayList<GroupMember>();
			int count = 0;
			for (DataRow dr : memberDt.getRows()) {
				// Groupmember赋值
				GroupMember groupMember = new GroupMember();
				try {
					groupMember.setMobileNo(MobileNo.parseFrom(dr.getString("MobileNo")));
				} catch (Exception e) {
					LOGGER.warn(String.format("getGroupInfo GroupId=%s logicalPool=%s no MobileNo", index.getGroupId(), index.getLogicalPool()), e);
					continue;
				}
				groupMember.setIdentity(dr.getInt("Identity"));
				if (1 == groupMember.getIdentity()  || 3 == groupMember.getIdentity()) {
					count++;
				}
				groupMember.setDisplayname(dr.getString("GroupNickname"));
				try {
					groupMember.setReferBy(MobileNo.parseFrom(dr.getString("ReferByMobileNo")));
				} catch (Exception e) {
					LOGGER.warn(String.format("getGroupInfo GroupId=%s logicalPool=%s no ReferByMobileNo", index.getGroupId(), index.getLogicalPool()), e);
					continue;
				}
				groupMemberList.add(groupMember);
			}
			groupInfo = new GroupInfo();
			if (infoDt.getRowCount() > 0) {
				DataRow row = infoDt.getRow(0);
				groupInfo.setGroupId(row.getInt("GroupId"));
				groupInfo.setConversationId(row.getString("ConversationId"));
				groupInfo.setSubject(row.getString("GroupName"));
				groupInfo.setCurrentMemberCount(count);
				groupInfo.setLimitMemberCount(row.getInt("MemberLimit"));
				groupInfo.setCreateTime(row.getDateTime("CreateTime"));
				groupInfo.setMembers(groupMemberList);
				MobileNo creator = null;
				try {
					creator = MobileNo.parseFrom(row.getString("Creator"));
				} catch (Exception e) {
					LOGGER.warn(String.format("getGroupInfo GroupId=%s logicalPool=%s no Creator", index.getGroupId(), index.getLogicalPool()), e);
					creator = null;
				}
				groupInfo.setCreator(creator);
				groupInfo.setExpires(row.getDateTime("DestroyTime"));
				groupInfo.setLogicalPool(row.getInt("LogicPool"));
				groupInfo.setDomain(row.getString("Domain"));
				groupInfo.setAttributesVersion(row.getInt("AttributesVersion"));
				groupInfo.setGroupType(row.getInt("GroupType"));

				// build Redis Cache
				groupCache.setGroupInfo(groupInfo);
				groupCache.setGroupMemberInfos(index.getGroupId(), groupMemberList);
				return groupInfo;
			}
		}
		return groupInfo;
	}

	/**
	 * 1. insert into GRP_GroupInfo(groupUri, conversationId, subject, crateor, ...)
	 * 2. for (groupMemberUris) {
	 * insert into GRP_GroupMember(groupUri, memberUri, ...)
	 * }
	 *
	 * @param index
	 * @param adminMobileNo
	 * @param conversationId
	 * @param subject
	 * @param members
	 */
	public void createGroup(GroupIndex index, MobileNo adminMobileNo, String conversationId, String subject, List<MobileNo> members) throws Exception {
		String infoSql = "INSERT INTO GRP_Group (GroupId, LogicPool, GroupName, EnableSearched, PortraitCrc, ValidType, CreateTime, DestroyTime, " +
				"MemberLimit, Status, Introduce,Bulletin, AttributesVersion, MemberlistMajorVersion, MemberlistMinorVersion, GroupType," +
				"EnableMemberInvited,FreezeTime, CategoryID, Domain, ConversationId, Creator)" +
				" values (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,? );";
		try {
			if (null == index) throw new RuntimeException("group index is null");

			Date nowUtc = DateUtils.getUTCNow();
			Object[] args = {
					index.getGroupId(),//GroupId
					index.getLogicalPool(),// LogicPool
					subject,// GroupName,
					2,// EnableSearched (1 可以被搜索, 2 不可以),
					0,// PortraitCrc, 0 表示默认头像
					3,// ValidType,3 需要神人验证才能加入该群
					nowUtc,// CreateTime,
					DateUtils.getOffset(nowUtc, 1, ChronoUnit.YEARS), //DestroyTime,  最后活动时间加上失效时间 等于销毁时间. 写的是失效时间为1年
					GroupConfiguration.INSTANCE.getMemberLimit(),// MemberLimit,
					1,// Status,
					"",// Introduce,不需要这个字段, 为空, 去掉插入
					"",// Bulletin, 不需要这个字段, 为空, 去掉插入
					1,// AttributesVersion,
					1,// MemberlistMajorVersion,
					1,// MemberlistMinorVersion,
					1,// GroupType,
					1,// EnableMemberInvited,
					"1900-1-1 0:00:00",// FreezeTime,
					0, // CategoryID,
					// Flag,
					GroupConfiguration.INSTANCE.getGroupDomain(),// Domain,
					conversationId, // ConversationId,
					adminMobileNo.toString() // Creater
			};
			getDatabase(index).executeNonQuery(infoSql, args);
			insertGroupMember(index, adminMobileNo, 1, nowUtc, adminMobileNo);
			if (members != null && members.size() > 0)
				for (MobileNo member : members) {
					try {
						inviteGroupMember(index, adminMobileNo, member);
					} catch (SQLException e) {
						LOGGER.error(String.format("insertGroupMembers Error index=%s member=%s   ", index, member), e);
						throw e;
					}
				}
		} catch (SQLException e) {
			LOGGER.error("create group error : {}", e);
			throw e;
		}
		// build Redis Cache
		try {
			getGroupInfo(index);
		} catch (Exception e) {
			LOGGER.error("build group cache error : {}", e);
		}
	}

	/**
	 * DENY：拒绝邀请
	 * MEMBER：接受邀请
	 * <p>
	 * switch (status) {
	 * case DENY:
	 * delete GroupMember...
	 * case MEMBER:
	 * update GRP_GroupMember ...
	 * }
	 *
	 * @param index
	 * @param role
	 */
	private boolean updateGroupMemberRole(GroupIndex index, MobileNo mobileNo, GroupMemberRole role) throws Exception {
		return updateGroupMemberIdentity(index, mobileNo, role.intValue());
	}

	public boolean updateGroupMemberStatus(GroupIndex index, MobileNo mobileNo, GroupMemberStatus status) throws Exception {
		return updateGroupMemberIdentity(index, mobileNo, status.intValue());
	}

	private boolean updateGroupMemberIdentity(GroupIndex index, MobileNo mobileNo, int identity) throws Exception {
		String sql = "UPDATE GRP_GroupMember SET Identity = ? WHERE GroupId =? AND MobileNo = ?;";
		try {
			if (null == index) throw new RuntimeException("group index is null");
			int ec = getDatabase(index).executeNonQuery(sql, identity, index.getGroupId(), mobileNo.toString());
			// update fetion MemberlistMinorVersion
			if (ec > 0) {
				String sqlVersion = "UPDATE GRP_Group SET MemberlistMajorVersion = MemberlistMajorVersion+1 WHERE  GroupId = ?";
				getDatabase(index).executeNonQuery(sqlVersion, index.getGroupId());
				// update Redis Cache
				try {
					GroupMember groupMemberInfo = groupCache.getGroupMemberInfo(index.getGroupId(), mobileNo);
					if (null == groupMemberInfo) {
						groupCache.clearGroup(index.getGroupId());
						getGroupInfo(index);
					} else {
						groupMemberInfo.setIdentity(identity);
						groupCache.setGroupMemberInfo(index.getGroupId(), groupMemberInfo);
					}
				} catch (Exception ex) {
					LOGGER.error(String.format("rebuild groupCache : updateGroupMemberRole Error index=%s member=%s  identity=%s  ", index, mobileNo, identity), ex);
				}
			}
			return ec > 0;
		} catch (SQLException e) {
			LOGGER.error(String.format("updateGroupMemberRole Error index=%s member=%s  identity=%s  ", index, mobileNo, identity), e);
			throw e;
		}
	}


	/**
	 * select @count = count(*) from GRP_GroupMember where GroupIndex = @GroupIndex and status in (1, 2, 3)
	 * if (@count < MAX_GROUP_CAPACITY) {
	 * update GRP_GroupMember set status = 3 where ... (groupUri, memberUri)
	 * return true;
	 * } else {
	 * do nothing
	 * return false;   // 开启逗你玩模式，无限403直到BYE删除
	 * }
	 *
	 * @param index
	 * @param mobileNo
	 * @return
	 */

	public boolean acceptGroupMemberInvitation(GroupIndex index, MobileNo mobileNo) throws Exception {
		GroupInfo groupInfo = getGroupInfo(index);
		if (groupInfo == null) {
			throw new GroupException(GroupError.GROUP_NOT_FOUND);
		}
		if (groupInfo.getCurrentMemberCount() >= groupInfo.getLimitMemberCount()) {
			throw new GroupException(GroupError.CAN_NOT_JOIN_MORE_GROUP);
		}
		return updateGroupMemberRole(index, mobileNo, GroupMemberRole.PARTICIPANT);
	}

	/**
	 * 1. 客户端回拒绝
	 * 2. 逗你玩模式客户端BYE
	 * 3. 移除成员
	 * 4. 成员主动退出
	 * delete from GRP_GroupMember where GroupIndex = ... and MemberUri = ...
	 *
	 * @param index
	 * @param mobileNo
	 * @remark 无法移除超管
	 */
	public void deleteGroupMember(GroupIndex index, MobileNo mobileNo) throws Exception {
		String sql1 = "select Identity from GRP_GroupMember where GroupId = ? and MobileNo = ?";
		String sql2 = "delete from GRP_GroupMember where GroupId = ? and MobileNo = ?";
		if (null == index) throw new RuntimeException("group index is null");

		DataTable dt = getDatabase(index).executeTable(sql1, index.getGroupId(), mobileNo.toString());
		if (dt != null && dt.getRowCount() > 0) {
			int identity = dt.getRow(0).getInt("Identity");
			if (identity == GroupMemberRole.CHAIRMAN.intValue() || identity == GroupMemberRole.MANAGER.intValue()) {
				throw new RuntimeException("Do not remove the manager!");
			} else {
				int ret = getDatabase(index).executeNonQuery(sql2, index.getGroupId(), mobileNo.toString());
				if (ret > 0) {
//					String sqlVersion1 = "UPDATE GRP_User SET GroupListVersion = GroupListVersion + 1 WHERE UserId = ?;";
					String sqlVersion2 = "UPDATE GRP_Group SET MemberlistMajorVersion = MemberlistMajorVersion + 1 WHERE GroupId = ?;";
					getDatabase(index).executeNonQuery(sqlVersion2, index.getGroupId());
					// update group cache
					groupCache.removeGroupMember(index.getGroupId(), mobileNo);
				}

			}
		}
	}

	/**
	 * @param index
	 * @param nickname
	 */
	public void updateGroupMemberNickname(GroupIndex index, MobileNo mobileNo, String nickname) throws Exception {
		if (null == nickname) {
			nickname = StringUtils.EMPTY;
		}
		String sql = "UPDATE GRP_GroupMember SET GroupNickname = ? WHERE GroupId =? AND MobileNo = ?;";
		try {
			if (null == index) throw new RuntimeException("group index is null");
			int ret = getDatabase(index).executeNonQuery(sql, nickname, index.getGroupId(), mobileNo.toString());
			if (ret > 0) {
				String sqlVersion = "UPDATE GRP_Group SET MemberlistMinorVersion = MemberlistMinorVersion + 1 WHERE GroupId = ?";
				getDatabase(index).executeNonQuery(sqlVersion, index.getGroupId());
				// update group cache
				try {
					GroupMember groupMemberInfo = groupCache.getGroupMemberInfo(index.getGroupId(), mobileNo);
					if (null == groupMemberInfo) {
						groupCache.clearGroup(index.getGroupId());
						getGroupInfo(index);
					} else {
						groupMemberInfo.setDisplayname(nickname);
						groupCache.setGroupMemberInfo(index.getGroupId(), groupMemberInfo);
					}
				} catch (InstantiationException e) {
					LOGGER.error(String.format("updateCache : updateGroupMemberNickname Error index=%s member=%s  nickname=%s  ", index, mobileNo, nickname), e);
				} catch (IllegalAccessException e) {
					LOGGER.error(String.format("updateCache : updateGroupMemberNickname Error index=%s member=%s  nickname=%s  ", index, mobileNo, nickname), e);
				} catch (Exception e) {
					LOGGER.error(String.format("rebuildCache : updateGroupMemberNickname Error index=%s member=%s  nickname=%s  ", index, mobileNo, nickname), e);
				}
			}
		} catch (SQLException e) {
			LOGGER.error(String.format("updateGroupMemberNickname Error index=%s member=%s  nickname=%s  ", index, mobileNo, nickname), e);
			throw e;
		}
	}


	/**
	 * 返回还能邀请的成员数量，已满返回"0"
	 *
	 * @param index
	 * @return
	 */
	public int getGroupMemberLimit(GroupIndex index) throws Exception {
		GroupInfo info = getGroupInfo(index);
		int limit = info.getLimitMemberCount();
		int currentCount = info.getCurrentMemberCount();
		int num = limit - currentCount;
		if (num <= 0) {
			return 0;
		}
		return num;
	}

	@Override
	// TODO: 记录REFERBY
	public int inviteGroupMember(GroupIndex index, MobileNo referByMobileNo, MobileNo mobileNo) throws Exception {
		if (null == index) {
			throw new IllegalArgumentException("group index is null");
		}

		if (null != mobileNo && StringUtils.isNullOrEmpty(mobileNo.toString())) {
			throw new IllegalArgumentException("mobileNo is null");
		}

		String getMemberSql = "select * from GRP_GroupMember where GroupId = ? and MobileNo =  ?";
		DataTable dataTable = getDatabase(index).executeTable(getMemberSql, index.getGroupId(), mobileNo.toString());
		if (dataTable.getRowCount() != 0) {
			LOGGER.info(String.format("invite Member is pending, groupId=%s member=%s ", index.getGroupId(), mobileNo));
			return dataTable.getRow(0).getInt("Identity");
		}

		insertGroupMember(index, mobileNo, 61, DateUtils.getUTCNow(), referByMobileNo);
		return -1;
	}

	private void insertGroupMember(GroupIndex index, MobileNo mobileNo, int identity, Date date, MobileNo referByMobileNo) throws Exception {
		String sql = "INSERT INTO  GRP_GroupMember(GroupId, Identity, GroupNickname, IICNickname,SmsPolicy,SmgPolicy," +
				"ClientData, MemberSid, MemberLogicalPool, UserId, AddGroupTime,  MobileNo,ReferByMobileNo) " +
				"VALUES ( ?,?,?,?,?,?,?,?,?,?,?,?,?);";
		FXCatalogIndex fxCatalogIndex = fxUserIndexService.getFXCatalogIndex(mobileNo);

		Object[] args = {index.getGroupId(), identity, "", "", 1, 1, "", fxCatalogIndex.getSid(), index.getLogicalPool(), fxCatalogIndex.getUserId(), date, mobileNo.toString(), referByMobileNo.toString()};
		try {
			if (null == index) throw new RuntimeException("group index is null");
			int ret = getDatabase(index).executeNonQuery(sql, args);
			if (ret > 0) {
				String sqlVersion = "UPDATE GRP_Group SET MemberlistMajorVersion = MemberlistMajorVersion + 1 WHERE GroupId = ?;";
				getDatabase(index).executeNonQuery(sqlVersion, index.getGroupId());
				// update Redis cache
				GroupMember member = new GroupMember();
				member.setIdentity(identity);
				member.setMobileNo(mobileNo);
				member.setReferBy(referByMobileNo);
				member.setStatus(GroupMemberStatus.PENDING);
				groupCache.setGroupMemberInfo(index.getGroupId(), member);
			}
		} catch (Exception e) {
			LOGGER.error(String.format("insertGroupMember Error index=%s member=%s identity=%s  ", index, mobileNo, identity), e);
			throw e;
		}
	}

	/**
	 * @param index
	 * @param originMobileNo
	 * @param targetMobileNo
	 */
	public void changeGroupAdmin(GroupIndex index, MobileNo originMobileNo, MobileNo targetMobileNo) throws Exception {
		String sql = "select Identity from GRP_GroupMember where GroupId = ? and MobileNo = ?";
		String sql_up_member = "UPDATE GRP_GroupMember SET Identity = ? WHERE GroupId =? AND MobileNo = ?;";
		DataTable dt = null;
		try {
			if (null == index) throw new RuntimeException("group index is null");

			dt = getDatabase(index).executeTable(sql, index.getGroupId(), originMobileNo.toString());
			int identity = dt.getRow(0).getInt("Identity");
			if (identity == GroupMemberRole.MANAGER.intValue() || identity == GroupMemberRole.CHAIRMAN.intValue()) {
				int ret = getDatabase(index).executeNonQuery(sql_up_member, 1, index.getGroupId(), targetMobileNo.toString());
				int ret2 = getDatabase(index).executeNonQuery(sql_up_member, 3, index.getGroupId(), originMobileNo.toString());
				if (ret2 > 0 && ret > 0) {
					String sqlVersion = "UPDATE GRP_Group SET MemberlistMajorVersion = MemberlistMajorVersion+1 WHERE  GroupId = ?;";
					getDatabase(index).executeNonQuery(sqlVersion, index.getGroupId());
					// update Redis Cache
					try {
						List<GroupMember> partGroupMembers = groupCache.getPartGroupMembers(index.getGroupId(), originMobileNo, targetMobileNo);
						if (partGroupMembers.size() == 0) {
							groupCache.clearGroup(index.getGroupId());
							getGroupInfo(index);
						} else {
							partGroupMembers.forEach(groupMember -> {
								if (groupMember.getMobileNo().equals(originMobileNo)) {
									groupMember.setIdentity(3);
								} else if (groupMember.getMobileNo().equals(targetMobileNo)) {
									groupMember.setIdentity(1);
								}
							});
							groupCache.setGroupMemberInfos(index.getGroupId(), partGroupMembers);
						}
					} catch (InstantiationException e) {
						LOGGER.error(String.format("update cache : changeGroupAdmin  error group=%s originUri=%s, targetUri=%s", index, originMobileNo.getCountryCode(), targetMobileNo.toString()), e);
					} catch (IllegalAccessException e) {
						LOGGER.error(String.format("update cache : changeGroupAdmin  error group=%s originUri=%s, targetUri=%s", index, originMobileNo.getCountryCode(), targetMobileNo.toString()), e);
					} catch (Exception e) {
						LOGGER.error(String.format("rebuild cache : changeGroupAdmin  error group=%s originUri=%s, targetUri=%s", index, originMobileNo.getCountryCode(), targetMobileNo.toString()), e);
					}
				}
			} else {
				throw new RuntimeException(String.format(" group:%s user:%s not SA", index, originMobileNo.toString()));
			}
		} catch (SQLException e) {
			LOGGER.error(String.format("changeGroupAdmin  error group=%s originUri=%s, targetUri=%s", index, originMobileNo.getCountryCode(), targetMobileNo.toString()), e);
			throw e;
		}

	}

	/**
	 * @param index
	 */
	public void dismissGroup(GroupIndex index) throws Exception {

		String sql_del_members = "delete from GRP_GroupMember where GroupId = ? ";
		String sql_del_group = "delete from GRP_Group where GroupId = ? ";
		try {
			if (null == index) throw new RuntimeException("group index is null");
			int delMembers = getDatabase(index).executeNonQuery(sql_del_members, index.getGroupId());
			int delGroup = getDatabase(index).executeNonQuery(sql_del_group, index.getGroupId());
			// clear Redis cache
			groupCache.clearGroup(index.getGroupId());
		} catch (SQLException e) {
			LOGGER.error("dismissGroup groupId=" + index.toString(), e);
			throw e;
		}
	}

	/**
	 * @param index
	 * @param subject
	 */
	public void updateGroupSubject(GroupIndex index, String subject) throws Exception {
		String sql = "UPDATE GRP_Group SET GroupName = ?,AttributesVersion=AttributesVersion+1 WHERE GroupId =? ;";
		try {
			getDatabase(index).executeNonQuery(sql, subject, index.getGroupId());
			// update Redis cache
			try {
				GroupInfo groupInfo = groupCache.getGroupInfo(index.getGroupId());
				if (null == groupInfo) {
					groupCache.clearGroup(index.getGroupId());
					getGroupInfo(index);
				} else {
					groupInfo.setSubject(subject);
					groupCache.setGroupInfo(groupInfo);
				}
			} catch (InstantiationException e) {
				LOGGER.error(String.format("update cache : updateGroupSubject groupId=%s  subject=%s", index.toString(), subject), e);
			} catch (IllegalAccessException e) {
				LOGGER.error(String.format("update cache : updateGroupSubject groupId=%s  subject=%s", index.toString(), subject), e);
			} catch (Exception e) {
				LOGGER.error(String.format("rebuild cache : updateGroupSubject groupId=%s  subject=%s", index.toString(), subject), e);
			}
		} catch (SQLException e) {
			LOGGER.error(String.format("updateGroupSubject groupId=%s  subject=%s", index.toString(), subject), e);
			throw e;
		}
	}

	@Override
	public boolean isChairMan(GroupIndex index, MobileNo mobileNo) throws Exception {
		String memberSql = "select * from GRP_GroupMember where GroupId = ? and MobileNo= ? limit 1";
		DataTable memberDt = getDatabase(index).executeTable(memberSql, index.getGroupId(), mobileNo.toString());
		boolean result = false;
		result = (memberDt != null && memberDt.getRowCount() > 0) ? 1 == memberDt.getRow(0).getInt("Identity") : false;
		return result;
	}

	@Override
	public MobileNo appointAdmin(GroupIndex index) throws Exception {
		MobileNo admin = null;
		String adminSql = "select * from GRP_GroupMember where GroupId = ?  and Identity = 1 ";

		DataTable dt = getDatabase(index).executeTable(adminSql, index.getGroupId());

		if (dt != null && dt.getRowCount() > 0) {
			String mobileNoStr = dt.getRow(0).getString("MobileNo");
			admin = MobileNo.parseFrom(mobileNoStr);
		} else {
			String memberSql = "select * from GRP_GroupMember where GroupId = ? and MobileNo is not null order by AddGroupTime desc";
			DataTable dtMember = getDatabase(index).executeTable(memberSql, index.getGroupId());
			if (dtMember != null && dtMember.getRowCount() > 0) {
				String mobileNoStr = dtMember.getRow(0).getString("MobileNo");
				admin = MobileNo.parseFrom(mobileNoStr);
			}
		}

		if (admin != null) {
			updateGroupMemberIdentity(index, admin, 1);
			LOGGER.info(String.format("appoint Admin  index=%s ,Admin=%s ", index.toJsonObject(), admin));
		}
		return admin;


	}

}
